//
//  NSDicitonaryBlocksViewController.m
//  BlocksKitLearn
//
//  Created by Elvis on 2017/8/18.
//  Copyright © 2017年 Elvis. All rights reserved.
//

#import "NSDicitonaryBlocksViewController.h"

static NSString *identifier = @"UITableViewCell";

@interface NSDicitonaryBlocksViewController ()<UITableViewDelegate, UITableViewDataSource>

@property (strong, nonatomic) NSDictionary *itemDic;

@property (strong, nonatomic) UITextView *textView;

@property (strong, nonatomic) UITableView *tableView;

@property (copy, nonatomic) NSArray *methods;

@end

@implementation NSDicitonaryBlocksViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.textView];
    [self.view addSubview:self.tableView];
}

/**
 * 简单遍历
 */
- (void)each{
    NSMutableString *string = [NSMutableString string];
    [self.itemDic bk_each:^(id key, id obj) {
        [string appendFormat:@"key = %@,obj = %@\n",key,obj];
    }];
    self.textView.text = string;
}

/**
 * 高效遍历,内部使用 background queue,多核设备下速度提升明显,但需要注意线程安全问题
 */
- (void)apply{
    NSMutableString *string = [NSMutableString string];
    [self.itemDic bk_apply:^(id key, id obj) {
        @synchronized (string) {
            [string appendFormat:@"key = %@,obj = %@\n",key,obj];
        }
    }];
    self.textView.text = string;
}
/**
 * 判断字典内部key/object 是否满足某个条件
 */
- (void)match{
    NSString *matchObj = [self.itemDic bk_match:^BOOL(id key, id obj) {
        return [obj isEqualToString:@"a"];
    }];
    
    self.textView.text = matchObj;
}

/**
 * 遍历并把字典内部满足给定条件 key/object 组装成新的字典
 */
- (void)select{
    NSDictionary *matchDic = [self.itemDic bk_select:^BOOL(NSString *key, id obj) {
        char condition = 'H';
        return *key.UTF8String < condition;
    }];
    
    self.textView.text = [NSString stringWithFormat:@"%@",matchDic];
}

/**
 * 遍历并把字典内部不满足给定条件 key/object 组装成新的字典
 */
- (void)reject{
    NSDictionary *matchDic = [self.itemDic bk_reject:^BOOL(NSString *key, id obj) {
        char condition = 'H';
        return *key.UTF8String < condition;
    }];
    self.textView.text = [NSString stringWithFormat:@"%@",matchDic];
}

/**
 * 遍历字典,对 object 进行操作,并把相同的 key和操作过的 object 组装成新的字典
 */
- (void)map{
    
    NSDictionary *newDic = [self.itemDic bk_map:^id(id key, id obj) {
        return [NSString stringWithFormat:@"%@=%@",key,obj];
    }];
    
    self.textView.text = [NSString stringWithFormat:@"%@",newDic];
}

/**
 * 遍历字典,判断满足条件的 key/value 是否存在
 */
- (void)any{
    BOOL exist = [self.itemDic bk_any:^BOOL(NSString *key, id obj) {
        char condition = 'S';
        return *key.UTF8String < condition;
    }];
    
    self.textView.text = [NSString stringWithFormat:@"%@",exist?@"存在":@"不存在"];
}

/**
 * 遍历字典,判断是否没有 key/value 满足给定的条件
 */
- (void)none{
    BOOL exist = [self.itemDic bk_none:^BOOL(NSString *key, id obj) {
        char condition = '1';
        return *key.UTF8String < condition;
    }];
    
    self.textView.text = [NSString stringWithFormat:@"%@",exist?@"没有":@"有"];
}

/**
 * 遍历字典,判断字典内的 key/value 是否都满足某种条件
 */
- (void)all{
    BOOL allIn = [self.itemDic bk_all:^BOOL(id key, id obj) {
        return [key isKindOfClass:[NSString class]] && [obj isKindOfClass:[NSString class]];
    }];
    
    self.textView.text = [NSString stringWithFormat:@"%@",allIn?@"全部满足":@"不全部满足"];
}

#pragma mark - <UITableViewDataSource>

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.methods.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    cell.textLabel.text = self.methods[indexPath.row];
    return cell;
}


#pragma mark - <UITableViewDelegate>

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    SEL selector = NSSelectorFromString(self.methods[indexPath.row]);
    IMP imp = [self methodForSelector:selector];
    void (*func)(id, SEL) = (void *)imp;
    func(self,selector);
}

#pragma mark - GET

- (NSDictionary *)itemDic{
    if (!_itemDic) {
        _itemDic = @{@"A":@"a",
                       @"B":@"b",
                       @"C":@"c",
                       @"D":@"d",
                       @"E":@"e",
                       @"F":@"f",
                       @"G":@"g",
                       @"H":@"h",
                       @"I":@"i",
                       @"J":@"j",
                       @"K":@"k",
                       @"L":@"l",
                       @"M":@"m",
                       @"N":@"n",
                       @"O":@"o",
                       @"P":@"p",
                       @"Q":@"q",
                       @"R":@"r",
                       @"S":@"s",
                       @"T":@"t",
                       @"U":@"u",
                       @"V":@"v",
                       @"W":@"w",
                       @"X":@"x",
                       @"Y":@"y",
                       @"Z":@"z"};
    }
    return _itemDic;
}

- (UITextView *)textView{
    if (!_textView) {
        _textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width , 200)];
        _textView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
        _textView.textColor = [UIColor whiteColor];
    }
    return _textView;
}

- (UITableView *)tableView{
    if (!_tableView) {
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, self.view.bounds.size.height - 200) style:UITableViewStylePlain];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.rowHeight = 40;
    }
    return _tableView;
}

- (NSArray *)methods{
    if (!_methods) {
        _methods = @[@"each",
                     @"apply",
                     @"match",
                     @"select",
                     @"reject",
                     @"map",
                     @"any",
                     @"none",
                     @"all"];
    }
    return _methods;
}

@end
